package educrypt.gui.components;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Toolkit;

import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.skin.BusinessSkin;
import org.pushingpixels.substance.api.skin.SubstanceGraphiteLookAndFeel;

import educrypt.gui.util.GuiUtil;
import educrypt.gui.view.AboutView;
import educrypt.gui.view.AnalysisView;
import educrypt.gui.view.CiphersView;
import educrypt.gui.view.ConsoleBigView;
import educrypt.gui.view.DatabaseView;
import educrypt.gui.view.EditorAlphabetView;
import educrypt.gui.view.EditorKeywordView;
import educrypt.gui.view.EditorTextOptionsView;
import educrypt.gui.view.MainView;
import educrypt.gui.view.TextPreviewView;
import educrypt.i18n.Messages;
import educrypt.resources.EduCryptResources;

class MainWindow implements MainView {

	/* Dialogs */
	private WaitDialog waitDialog;
	private EditorKeywordDialog editorKeywordDialog;
	private EditorAlphabetDialog editorAlphabetDialog;
	private EditorTextTypeDialog editorTextTypeDialog;
	private EditorTextLanguageDialog editorLanguageDialog;
	private TextPreviewDialog textPreviewDialog;
	private ConsoleBigDialog consoleBigDialog;

	/* Panels */
	private JFrame frame;
	private JPanel mainPanel, centralPanel;
	private GoToPanel goToPanel;
	private CryptanalysisPanel cryptanalysisPanel;
	private CiphersPanel ciphersPanel;
	private AboutPanel aboutPanel;
	private AnalysisPanel analysisPanel;
	private DatabasePanel databasePanel;

	/**
	 * Create the application.
	 */
	public MainWindow() {
		initialize();
		frame.setVisible(true);
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		setLookAndFeel();
		initializeMainFrame();

	}

	private void setLookAndFeel() {
		// If false java uses default system window decorators
		JFrame.setDefaultLookAndFeelDecorated(true);
		JDialog.setDefaultLookAndFeelDecorated(true);

		setSubstanceLookAndFeel();
	}

	private void setSubstanceLookAndFeel() {
		try {
			// Setting Look&Feel and Skin
			UIManager.setLookAndFeel(new SubstanceGraphiteLookAndFeel());
			SubstanceLookAndFeel.setSkin(new BusinessSkin());
			// SwingUtilities.updateComponentTreeUI(ventana);
		} catch (UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
	}

	private void initializeMainFrame() {
		frame = new JFrame();
		frame.setResizable(false);
		frame.setIconImage(Toolkit.getDefaultToolkit().getImage(
				EduCryptResources.getImageURL("padlock_icon.png")));
		frame.setTitle(Messages.getString("guiTitle"));
		frame.setLocation(80, 80);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(new BorderLayout(0, 0));

		initializeComponents();

		frame.getContentPane().add(mainPanel, BorderLayout.CENTER);
		frame.pack();

		toFront();
	}

	private void initializeComponents() {
		mainPanel = new JPanel();
		mainPanel.setSize(850, 650);
		mainPanel.setPreferredSize(mainPanel.getSize());

		/* Panels */
		this.goToPanel = new GoToPanel();
		this.cryptanalysisPanel = new CryptanalysisPanel();
		this.ciphersPanel = new CiphersPanel();
		this.aboutPanel = new AboutPanel();
		this.analysisPanel = new AnalysisPanel();
		this.databasePanel = new DatabasePanel();
		this.centralPanel = aboutPanel;

		mainPanel.setLayout(new BorderLayout(0, 0));
		mainPanel.add(goToPanel, BorderLayout.WEST);
		mainPanel.add(centralPanel, BorderLayout.CENTER);

		/* Dialogs */
		this.editorKeywordDialog = new EditorKeywordDialog(this.frame);
		this.editorAlphabetDialog = new EditorAlphabetDialog(this.frame);
		this.editorTextTypeDialog = new EditorTextTypeDialog(this.frame);
		this.editorLanguageDialog = new EditorTextLanguageDialog(this.frame);
		this.waitDialog = new WaitDialog(this.frame);
		this.textPreviewDialog = new TextPreviewDialog(this.frame);
		this.consoleBigDialog = new ConsoleBigDialog(this.frame);
	}

	/* Getters */
	@Override
	public GoToPanel getActionPanel() {
		return goToPanel;
	}

	@Override
	public CryptanalysisPanel getCryptanalysisPanel() {
		return cryptanalysisPanel;
	}

	@Override
	public CiphersView getCiphersPanel() {
		return ciphersPanel;
	}

	@Override
	public AnalysisView getAnalysisPanel() {
		return analysisPanel;
	}

	@Override
	public DatabaseView getDatabasePanel() {
		return databasePanel;
	}

	@Override
	public AboutView getAboutPanel() {
		return aboutPanel;
	}

	@Override
	public EditorKeywordView getEditorKeywordDialog() {
		return editorKeywordDialog;
	}

	@Override
	public EditorAlphabetView getEditorAlphabetDialog() {
		return editorAlphabetDialog;
	}

	@Override
	public EditorTextOptionsView getEditorTextTypeDialog() {
		return editorTextTypeDialog;
	}

	@Override
	public EditorTextOptionsView getEditorTextLanguageDialog() {
		return editorLanguageDialog;
	}

	@Override
	public TextPreviewView getTextPreviewDialog() {
		return textPreviewDialog;
	}

	@Override
	public ConsoleBigView getConsoleBigDialog() {
		return consoleBigDialog;
	}

	/* END Getters */

	@Override
	public void goToCiphers() {
		this.goTo(ciphersPanel);
	}

	@Override
	public void goToAnalysis() {
		this.goTo(analysisPanel);
	}

	@Override
	public void goToCryptAnalysis() {
		this.goTo(cryptanalysisPanel);
	}

	@Override
	public void goToDatabase() {
		this.goTo(databasePanel);
	}

	@Override
	public void goToAbout() {
		this.goTo(aboutPanel);
	}

	@Override
	public void showWaitDialog(boolean visible) {
		if (visible) {
			this.waitDialog.open();
		} else {
			this.waitDialog.close();
		}
	}

	private void goTo(JPanel visiblePanel) {
		mainPanel.remove(centralPanel);
		centralPanel = visiblePanel;
		mainPanel.add(centralPanel, BorderLayout.CENTER);
		mainPanel.validate();
		mainPanel.repaint();
	}

	@Override
	public void showExceptionDialog(String message) {
		GuiUtil.showExceptionDialog(this.frame, message);
	}

	@Override
	public void showExceptionDialog() {
		GuiUtil.showExceptionDialog(this.frame);
	}

	public Dimension getSize() {
		return frame.getSize();
	}

	public void toFront() {
		frame.setVisible(true);
		frame.setState(Frame.NORMAL);
		frame.setAlwaysOnTop(true);
		frame.toFront();
		frame.requestFocus();
		frame.setAlwaysOnTop(false);

		// frame.toFront();
		// frame.repaint();
	}
}
